package com.zf.spring.microservice.uaa.web;

import io.jsonwebtoken.Claims;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.zf.spring.microservice.uaa.domain.User;
import com.zf.spring.microservice.uaa.domain.UserApiScope;
import com.zf.spring.microservice.uaa.repository.UserApiScopeRepository;
import com.zf.spring.microservice.uaa.repository.UserRepository;
import com.zf.spring.microservice.uaa.token.jwt.JwtConfiguration;
import com.zf.spring.microservice.uaa.token.jwt.JwtTokenProvider;
import com.zf.spring.microservice.uaa.token.jwt.UAAClaims;
import com.zf.spring.microservice.uaa.web.vo.JWTToken;
import com.zf.spring.microservice.uaa.web.vo.LoginVO;

/**
 * 获取token
 * 
 * @author zhangfeng
 * 
 */
@RestController
@RequestMapping("/")
public class TokenController {
	@Autowired
	UserRepository userRepository;

	@Autowired
	UserApiScopeRepository userApiScopeRepository;

	@Autowired
	JwtConfiguration jwtConfiguration;

	@Autowired
	JwtTokenProvider jwtTokenProvider;

	@PostMapping("/token/byPhone")
	public ResponseEntity<?> getTokenByPhone(@RequestBody LoginVO loginVO) {
		User user = userRepository.findByPhoneAndPassword(loginVO.getPhone(),
				loginVO.getPassword());
		List<UserApiScope> userApiScopes = getUserApiScope(user);
		return ResponseEntity.ok(new JWTToken(jwtTokenProvider
				.createToken(parseClaims(user, userApiScopes))));
	}

	@PostMapping("/token/byEmail")
	public ResponseEntity<?> getTokenByEmail(@RequestBody LoginVO loginVO) {
		User user = userRepository.findByEmailAndPassword(loginVO.getEmail(),
				loginVO.getPassword());
		List<UserApiScope> userApiScopes = getUserApiScope(user);
		return ResponseEntity.ok(new JWTToken(jwtTokenProvider
				.createToken(parseClaims(user, userApiScopes))));
	}

	@PostMapping("/token/byAccountId")
	public ResponseEntity<?> getTokenByAccountId(@RequestBody LoginVO loginVO) {
		User user = userRepository.findByAccountIdAndPassword(
				loginVO.getAccountId(), loginVO.getPassword());
		List<UserApiScope> userApiScopes = getUserApiScope(user);
		return ResponseEntity.ok(new JWTToken(jwtTokenProvider
				.createToken(parseClaims(user, userApiScopes))));
	}

	@RequestMapping("/token/parse")
	public Claims parseToken(String token) {
		return jwtTokenProvider.parseToken(token);
	}

	private List<UserApiScope> getUserApiScope(User user) {
		if (user == null) {
			return new ArrayList<UserApiScope>();
		}
		Page<UserApiScope> scopes = userApiScopeRepository.findByAccountId(
				user.getAccountId(), new PageRequest(0, 10000));
		return scopes.getContent();
	}

	private UAAClaims parseClaims(User user, List<UserApiScope> userApiScopes) {
		UAAClaims uaaClaims = new UAAClaims();
		uaaClaims.setIssuer(jwtConfiguration.getIss());
		uaaClaims.setIssuedAt(new Date());
		uaaClaims.setAudience(String.valueOf(user.getAccountId()));
		uaaClaims.setId(UUID.randomUUID().toString());
		uaaClaims.setUserName(user.getUserName());
		uaaClaims.setExpiration(new Date(System.currentTimeMillis()
				+ jwtConfiguration.getExpm() * 1000 * 60));
		uaaClaims.setEmail(user.getEmail());
		uaaClaims.setPhone(user.getPhone());
		uaaClaims.setSubject(String.valueOf(user.getAccountId()));
		uaaClaims.setNotBefore(new Date());
		// scope
		String scopes[] = new String[userApiScopes.size()];
		for (int i = 0; i < userApiScopes.size(); i++) {
			scopes[i] = userApiScopes.get(i).getApiInfo();
		}
		uaaClaims.setScope(scopes);
		return uaaClaims;

	}
}
